package com.noble.meether.chat.ui.agora.manager;

import android.content.Intent;
import android.view.SurfaceView;
import android.view.View;

import com.faceunity.MRender;
import com.noble.glamour.module.logic.application.App;
import com.noble.glamour.module.logic.application.ModuleMgr;
import com.noble.glamour.module.logic.request.RequestComplete;
import com.noble.library.dir.DirType;
import com.noble.library.log.PLogger;
import com.noble.library.observe.ModuleBase;
import com.noble.library.request.DownloadListener;
import com.noble.library.utils.FileUtil;
import com.noble.meether.chat.ui.agora.RtcUIShow;
import com.noble.meether.chat.ui.agora.act.bean.Props;
import com.noble.meether.chat.ui.agora.act.bean.RtcProps;
import com.noble.meether.chat.ui.agora.act.vfloat.RtcFloatService;
import com.noble.meether.chat.ui.agora.beauty.ViewFaceBeautify;
import com.noble.meether.chat.ui.agora.model.AGEventHandler;
import com.noble.meether.chat.ui.agora.model.AgoraConstant;
import com.noble.meether.chat.ui.agora.model.EngineConfig;
import com.noble.meether.chat.ui.agora.model.IRtcEngineHandler;
import com.noble.meether.chat.ui.agora.util.RtcJointChannel;
import com.noble.meether.chat.ui.agora.util.RtcSubUtil;
import com.noble.meether.chat.ui.agora.util.RtcTimerUtil;
import com.noble.meether.chat.ui.agora.util.RtcWorkerThread;
import com.noble.meether.chat.unread.UnreadMgr;
import com.trello.rxlifecycle2.components.support.RxAppCompatActivity;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import io.agora.rtc.IRtcEngineEventHandler;
import io.agora.rtc.RtcEngine;

/**
 * 音视频引擎相关管理类
 * <p>
 * Created by Su on 2017/3/17.
 */
public class RtcEngineMgr implements ModuleBase {
    private static EngineConfig mEngineConfig;        // 配置信息
    private static RtcProps props; // 道具信息

    @Override
    public void init() {
    }

    @Override
    public void release() {
    }

    /**
     * 释放音视频引擎
     */
    public void releaseEngine() {
        worker().release();
        ModuleMgr.getRtcEnginMgr().deInitWorkerThread();
        ModuleMgr.getRtcEnginMgr().removeEventHandler(RtcJointChannel.getInstance().handler);
        PLogger.d("susu::  releaseEngine");
    }

    /**
     * 关闭通信中各种计时
     */
    public void releaseLocalTimer() {
        RtcTimerUtil.getInstance().releaseAll();
    }


    /**
     * 关闭通信中各种轮询
     */
    public void releaseLocalPoll() {
        RtcSubUtil.getInstance().stopVideoChatTime();
        RtcSubUtil.getInstance().stopTinyVideoChatTime();
        RtcSubUtil.getInstance().stopPicTime();
    }

    public void releaseAll() {
        UnreadMgr.whisperId = 0;
        getEngineConfig().isBusy = false;
        getEngineConfig().isCalling = false;
        releaseLocalTimer();
        releaseLocalPoll();
        releaseEngine();
        RtcTimerUtil.getInstance().stopStatisChatTime();
        RtcTimerUtil.getInstance().stopStatisInvTime();
        RtcTimerUtil.getInstance().stopStatisTipsTime();
    }

    public RtcEngineMgr() {
        mEngineConfig = new EngineConfig();
        mEventHandlerList = new ConcurrentHashMap<>();
        mRtcEventHandler = new IRtcEngineHandler(mEventHandlerList);
    }


    // ================================ SDK工作线程初始化 ===========================================
    private static RtcWorkerThread mWorkerThread;

    public synchronized void initWorkerThread() {
        if (mWorkerThread == null) {
            mWorkerThread = new RtcWorkerThread(App.getContext());
            mWorkerThread.start();

            mWorkerThread.waitForReady();
        }
    }

    public synchronized static RtcWorkerThread getWorkerThread() {
        return mWorkerThread;
    }

    public synchronized void deInitWorkerThread() {
        if (mWorkerThread != null) {
            mWorkerThread.exit();
            try {
                mWorkerThread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            mWorkerThread = null;
        }
    }

    // ============================ FaceU美颜自定义View回调监听 ============================================
    private ViewFaceBeautify beautify = null;

    public void switchBeauty() {
        if (beautify == null) return;
        if (beautify.getVisibility() == View.GONE) {
            beautify.setVisibility(View.VISIBLE);
        }
    }

    public void setFaceUListener(ViewFaceBeautify beautify) {
        if (beautify == null) return;

        this.beautify = beautify;
        beautify.setBeautifyInterface(new ViewFaceBeautify.BeautityFaceInterface() {
            @Override
            public void onEffectItemSelected(String effectItemName) {
            }

            @Override
            public void onFilterSelected(String filterName) {
                MRender.setCurrentFilterByPosition(filterName);
            }

            @Override
            public void onBlurLevelSelected(int level) {
                MRender.setBlurLevel(level);
            }

            @Override
            public void onColorLevelSelected(int progress, int max) {
                MRender.setColorLevel(progress, max);
            }

            @Override
            public void onCheekThinSelected(int progress, int max) {
                MRender.setCheekThinning(progress, max);
            }

            @Override
            public void onEnlargeEyeSelected(int progress, int max) {
                MRender.setEyeEnlarging(progress, max);
            }

            @Override
            public void onFaceShapeSelected(int faceShape) {
                MRender.setFaceShape(faceShape);
            }

            @Override
            public void onFaceShapeLevelSelected(int progress, int max) {
                MRender.setFaceShapeLevel(progress, max);
            }

            @Override
            public void onRedLevelSelected(int progress, int max) {
                MRender.setRedLevel(progress, max);
            }
        });
    }


    // ============================ 注册回调监听 ============================================
    private static IRtcEngineEventHandler mRtcEventHandler;                              // 引擎回调监听
    private final ConcurrentHashMap<AGEventHandler, Integer> mEventHandlerList; // 维护回调监听

    /**
     * 注册监听
     */
    public void addEventHandler(AGEventHandler handler) {
        this.mEventHandlerList.put(handler, 0);
    }

    /**
     * 反注册指定监听
     */
    public void removeEventHandler(AGEventHandler handler) {
        this.mEventHandlerList.remove(handler);
    }

    /**
     * 获取引擎监听回调
     */
    public IRtcEngineEventHandler getEngineHandler() {
        if (mRtcEventHandler == null) mRtcEventHandler = new IRtcEngineHandler(mEventHandlerList);
        return mRtcEventHandler;
    }

    // ============================ 对外提供接口 ============================================

    /**
     * 获取引擎配置
     */
    public EngineConfig getEngineConfig() {
        if (mEngineConfig == null) mEngineConfig = new EngineConfig();
        return mEngineConfig;
    }

    public void releaseEngineConfig() {
        if (mEngineConfig != null)
            mEngineConfig.reset();
    }

    /**
     * 获取引擎对象
     */
    public RtcEngine getRtcEngine() {
        return worker().getRtcEngine();
    }

    /**
     * 加入频道
     */
    public final void joinChannel(RxAppCompatActivity activity) {
        worker().joinChannel();
        RtcSubUtil.getInstance().reqCheckStart(activity); // 加入频道开始执行后，延迟调用check接口，若失败，则重新调用start接口
    }

    /**
     * 离开频道
     *
     * @param channel 渠道ID
     */
    public final void leaveChannel(String channel) {
        worker().leaveChannel(channel);
    }

    /**
     * 视频: 绑定已方容器，并开启视频预览
     *
     * @param start 是否开启视频
     * @param view  视频显示视窗容器
     */
    public final void preview(boolean start, SurfaceView view) {
        worker().preview(start, view, 0);
    }

    /**
     * 视频： 配置
     *
     * @param vProfile 视频属性：{@see 'https://docs.agora.io/cn/user_guide/API/android_api.html'}
     */
    public final void configVideoEngine(int vProfile, String encryptionKey, String encryptionMode) {
        worker().configVideoEngine(vProfile, encryptionKey, encryptionMode);
    }

    /**
     * 切换摄像头
     */
    public final void switchCamera() {
        worker().switchCamera();
    }

    /**
     * 切换话筒
     *
     * @param defaultToSpeaker true: 外放  false: 听筒
     */
    public final void switchMicro(boolean defaultToSpeaker) {
        worker().switchMicro(defaultToSpeaker);
    }

    /**
     * 开关扬声器
     *
     * @param enabled true: 外放  false: 默认路由
     */
    public final void setEnableSpeakerphone(boolean enabled) {
        worker().setEnableSpeakephone(enabled);
    }

    /**
     * 静音本地音频流
     *
     * @param muted true: 麦克风静音  false: 取消静音
     */
    public final void switchLocalAudioStream(boolean muted) {
        worker().switchLocalAudioStream(muted);
    }

    /**
     * 获取工作线程
     */
    private RtcWorkerThread worker() {
        initWorkerThread();
        return mWorkerThread;
    }

    // ===================================== 通信悬浮窗 ====================================================

    /**
     * 开启通信悬浮窗
     */
    public void startRtcFloatService() {
        App.activity.startService(new Intent(App.activity, RtcFloatService.class));
        RtcJointChannel.getInstance().setFloatStatus(true);
        App.activity.finish();
    }

    /**
     * 关闭悬浮窗
     */
    public void justStopRtcFloatService() {
        RtcJointChannel.getInstance().setFloatStatus(false);
        App.activity.stopService(new Intent(App.activity, RtcFloatService.class));
    }

    public void stopRtcFloatService() {
        skipLogic();
        justStopRtcFloatService();
    }

    // 悬浮窗关闭逻辑
    private void skipLogic() {
        // 未接通
        if (!getEngineConfig().mJoinStatus) {
            if (getEngineConfig().mInviteType == AgoraConstant.RTC_CHAT_BEINVITE) {
                RtcUIShow.showRtcInitAct(App.getContext());
                return;
            }

            // 返回邀请等待界面
            RtcUIShow.showRtcInitAct(App.getContext());
            return;
        }

        // 返回音频聊天
        if (getEngineConfig().mChatType == AgoraConstant.RTC_CHAT_VOICE) {
            RtcUIShow.showRtcVoiceAct(App.activity);
            return;
        }

        // 返回视频聊天
        RtcUIShow.showRtcVideoAct(App.activity);
    }

    // ================================= 音视频优化版 ==========================
    /**
     * 获取道具列表
     */
    public RtcProps getPropList() {
        return props;
    }

    public void initPropList() {
        if (props == null)
            reqGetPropList();
    }

    public void reqGetPropList() {
//        ModuleMgr.getHttpMgr().reqPostAndCacheHttp(UrlParam.reqGetPropList, null, new RequestComplete() {
//            @Override
//            public void onRequestComplete(HttpResponse response) {
//                if (!response.isOk()) return;
//                props = (RtcProps) response.getBaseData();
//                downloadProp();  // 下载道具任务
//
//                if (!response.isCache()) {
//                    propUrls.add("end");  // 占位
//                    PSP.getInstance().put("RTC_VIDEO_PROP", propUrls.toString());
//                }
//            }
//        });
    }

    /**
     * 使用道具
     *
     * @param propId   // 道具id
     * @param propType // 0 给自己使用 1 给对方使用
     */
    public void reqUsingProp(int propId, int propType, RequestComplete complete) {
        Map<String, Object> postParams = new HashMap<>();
        postParams.put("vc_id", getEngineConfig().mVcid);
        postParams.put("prop_id", propId);
        postParams.put("prop_type", propType);
//        ModuleMgr.getHttpMgr().reqPostNoCacheHttp(UrlParam.reqUsingProp, postParams, complete);
    }

    private List<String> propUrls = new ArrayList<>();  // 维护道具地址

    /**
     * 下载道具
     * <p>
     * /storage/emulated/0/xiaou/download/aixingou.mp3
     */
    private void downloadProp() {
        List<Props> list = props.getPropsList();
        if (list == null || list.isEmpty()) return;
        if (propUrls == null) propUrls = new ArrayList<>();

        propUrls.clear();
        propUrls.add("none");
        for (int i = 0; i < list.size(); i++) {
            String url = list.get(i).getBundle();
            propUrls.add(url);
            String filePath = DirType.getDownloadDir() + FileUtil.getFileNameByPath(url) + ".mp3";

            // 已存在该文件
            if (FileUtil.isExist(filePath)) continue;

            ModuleMgr.getHttpMgr().download(url, filePath, new DownloadListener() {
                @Override
                public void onStart(String url, String filePath) {
                }

                @Override
                public void onProcess(String url, int process, long size) {
                }

                @Override
                public void onSuccess(String url, String filePath) {
                }

                @Override
                public void onFail(String url, Throwable throwable) {
                }
            });
        }
    }

    // ============================ 额外需求 ==============================
    /**
     * 悬浮窗授权时，跳到系统授权页时保存状态，禁止桌面悬浮窗
     */
    private boolean permissionStatus = false;   // 是否处于系统权限申请页

    public boolean getPermissionStatus() {
        return permissionStatus;
    }

    public void setPermissionStatus(boolean permissionStatus) {
        this.permissionStatus = permissionStatus;
    }
}
